/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package net.worldscale.xp.wslib.im.jabber.util;

import java.io.PrintStream;
import net.worldscale.xp.wslib.im.jabber.JabberClient;
import org.w3c.dom.Attr;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.w3c.dom.Text;

/**
 *
 * @author Kun
 */
public class XmppStanzaPrinter implements JabberClient.StreamListener {

    public XmppStanzaPrinter() {
    }

    public void onStanza(Element stanza) {
        final PrintStream out = System.out;
        out.println("<stanza>");
        this.print(out, 1, stanza);
        out.println("</stanza>");
    }

    public void onStreamClose() {
    }

    public void onStreamOpen() {
    }

    private static String getTabString(int depth) {
        final StringBuffer sbuf = new StringBuffer();
        for (int i = depth * 4; i > 0; i--) {
            sbuf.append(' ');
        }
        return sbuf.toString();
    }

    private static void print(PrintStream out, int depth, Text text) {
        out.println(getTabString(depth) + "    " + text.getData());
    }

    private static void print(PrintStream out, int depth, Element element) {
        if (depth > 32) {
            throw new RuntimeException("XMPP DOM is too deep.");
        }
        final String tag = element.getTagName();
        {
            // element open
            out.print(getTabString(depth) + "<" + tag);
            final NamedNodeMap attrs = element.getAttributes();
            final int len = attrs.getLength();
            for (int i = 0; i < len; i++) {
                final Attr attr = (Attr) attrs.item(i);
                out.print(" " + attr.getName() + "='" + attr.getValue() + "'");
            }
            out.println(">");
        }
        final NodeList nl = element.getChildNodes();
        final int len = nl.getLength();
        for (int i = 0; i < len; i++) {
            final Node childNode = nl.item(i);
            if (childNode instanceof Element) {
                print(out, depth + 1, (Element) childNode);
            } else if (childNode instanceof Text) {
                print(out, depth + 1, (Text) childNode);
            } else {
            }
        }
        {
            // element close
            out.println(getTabString(depth) + "</" + tag + ">");
        }
    }
}
